//package com.jrx.anytxn.customer.plugins;
//
//import com.google.common.collect.Maps;
//import com.jrx.anytxn.common.annotation.EnableHistoryLogAnnotation;
//import com.jrx.anytxn.common.uitl.StringUtils;
//import com.jrx.anytxn.customer.entity.CmCustomerMaintenanceLog;
//import com.jrx.anytxn.number.exception.SegmentException;
//import com.jrx.anytxn.number.service.ISegmentService;
//import net.sf.jsqlparser.schema.Column;
//import net.sf.jsqlparser.statement.select.PlainSelect;
//import net.sf.jsqlparser.statement.select.Select;
//import net.sf.jsqlparser.util.SelectUtils;
//import org.apache.commons.collections.CollectionUtils;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.*;
//import org.apache.ibatis.plugin.*;
//import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.session.Configuration;
//import org.apache.ibatis.session.RowBounds;
//import org.apache.ibatis.session.defaults.DefaultSqlSession;
//import org.apache.ibatis.type.TypeHandlerRegistry;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.lang.reflect.Method;
//import java.sql.SQLException;
//import java.text.DateFormat;
//import java.util.*;
//
///**
// * 历史记录plugin
// * @author: zhenghaopu
// * @date: 2019/8/26 15:32
//*/
//@Intercepts(value = {
//        @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
//@Component
//public class HistoryLogPlugins implements Interceptor {
//
//
//    private static Logger logger = LoggerFactory.getLogger(HistoryLogPlugins.class);
//    private static final String CUSTOMQUERY = "_CUSTOMQUERY";
//
//    @Autowired
//    private ISegmentService iSegmentService;
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        // 拦截目标
//        Object target = invocation.getTarget();
//        if (target instanceof Executor) {
//            Executor executor=(Executor)target;
//            Object[] args = invocation.getArgs();
//            MappedStatement ms = (MappedStatement) args[0];
//            Object parameter = args[1];
//
//            //获取注解
//            EnableHistoryLogAnnotation enableHistoryLogAnnotation = getEnableHistoryLogAnnotationAnnotation(ms.getId());
//            String type;
//            //没有注解  则不进行处理
//            if(enableHistoryLogAnnotation==null){
//                return  invocation.proceed();
//            }
//            //获取历史记录类型
//            type=enableHistoryLogAnnotation.value();
//            //判断是否是更新语句 不是则不进行处理
//            if(!ms.getSqlCommandType().equals(SqlCommandType.UPDATE)){
//                return invocation.proceed();
//            }
//                //获取历史信息对象
//            HistoryLog txnHistoryLog= HistoryLogHelper.getLocalHistory();
//            //不存在则不进行处理
//            if(txnHistoryLog == null){
//                return invocation.proceed();
//            }
//
//            BoundSql boundSql = ms.getBoundSql(parameter);
//            String sql = showSql(ms.getConfiguration(),boundSql);
//            //解析sql
//            SqlParserInfo sqlParserInfo=new SqlParserInfo(sql);
//            ArrayList<HashMap<String, Object>> preDataList = null;
//            try {
//                //获取更新前数据列表
//                preDataList = getPreUpdateData(parameter, executor, ms, sqlParserInfo);
//            }catch(Exception e){
//                logger.error("异常:",e);
//            }
//            Object result = invocation.proceed();
//            try{
//                //
//                if(((int)result)>0 && CollectionUtils.isNotEmpty(preDataList)){
//                    // 方法执行之后处理数据
//                    //获取更新字段列表
//                    Map<String, Object> updateDataMap = getParameter(sqlParserInfo);
//
//                    // 执行Update方法，除了查询之外的Insert，Delete，Update都是属于Update方法
//                    List<CmCustomerMaintenanceLog> customerMaintenanceLogs =getCmCustomerMaintenanceLog(txnHistoryLog,
//                            preDataList,updateDataMap,type,sqlParserInfo.getTableName());
//                    if(CollectionUtils.isNotEmpty(customerMaintenanceLogs)){
//                        MappedStatement insertMs=
//                                ms.getConfiguration().getMappedStatement("com.jrx.anytxn.customer.mapper.ext" +
//                                        ".ExtCmCustomerMaintenanceLogMapper.batchInsertSelective");
//                        executor.update(insertMs,wrapCollection(customerMaintenanceLogs));
//                    }
//                }
//                return  result;
//            }catch(Exception e){
//                logger.error("异常:",e);
//                return  result;
//            }
//        }else{
//            return invocation.proceed();
//        }
//    }
//
//    @Override
//    public Object plugin(Object target) {
//        return Plugin.wrap(target, this);
//    }
//
//    @Override
//    public void setProperties(Properties properties) {
//        logger.debug("参数设置，可以为空");
//    }
//
//    /*
//    *获取更新前数据
//     */
//    private ArrayList<HashMap<String, Object>> getPreUpdateData(Object parameter,
//                                                                Executor executor, MappedStatement ms,SqlParserInfo sqlParserInfo) throws SQLException {
//
//
//        String selectSqlString = getSelectStr(sqlParserInfo);
//
//        //设置查询BoundSql
//        BoundSql queryBoundSql = new BoundSql(ms.getConfiguration(), selectSqlString, null,
//                null);
//        //获取新的MappedStatement 进行查询
//        MappedStatement selectMappedStatement = newHashMapMappedStatement(ms);
//
//        Object queryResultList;
//            //查询获取结果
//        queryResultList = executor.query(selectMappedStatement, parameter, RowBounds.DEFAULT, null, null,
//                    queryBoundSql);
//
//        return (ArrayList<HashMap<String, Object>>) queryResultList;
//    }
//
//    /*
//     *生成select语句
//     */
//    private String getSelectStr(SqlParserInfo sqlParserInfo){
//        Column id=new Column("id");
//        Column recordVersionNumber=new Column("record_version_number");
//        sqlParserInfo.getColumns().add(id);
//        sqlParserInfo.getColumns().add(recordVersionNumber);
//        Column[] selectColumns = sqlParserInfo.getColumns().toArray(new Column[0]);
//        Select select = SelectUtils.buildSelectFromTableAndExpressions(sqlParserInfo.getTable(), selectColumns);
//        PlainSelect selectPlain = (PlainSelect) select.getSelectBody();
//        selectPlain.setWhere(sqlParserInfo.getWhereExpression());
//        String selectStr=select.toString();
//        sqlParserInfo.getColumns().remove(id);
//        sqlParserInfo.getColumns().remove(recordVersionNumber);
//        return selectStr;
//    }
//    /*
//     * 构建新的MappedStatement
//     */
//    private MappedStatement newHashMapMappedStatement(MappedStatement ms) {
//        MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId() + CUSTOMQUERY, ms.getSqlSource(), ms.getSqlCommandType());
//        builder.resource(ms.getResource());
//        builder.fetchSize(ms.getFetchSize());
//        builder.statementType(ms.getStatementType());
//        builder.keyGenerator(ms.getKeyGenerator());
//        if (ms.getKeyProperties() != null && ms.getKeyProperties().length != 0) {
//            StringBuilder keyProperties = new StringBuilder();
//            for (String keyProperty : ms.getKeyProperties()) {
//                keyProperties.append(keyProperty).append(",");
//            }
//            keyProperties.delete(keyProperties.length() - 1, keyProperties.length());
//            builder.keyProperty(keyProperties.toString());
//        }
//        builder.timeout(ms.getTimeout());
//        builder.parameterMap(ms.getParameterMap());
//        List<ResultMap> resultMaps = new ArrayList<>();
//        List<ResultMapping> emptyResultMapping = new ArrayList<>(0);
//        ResultMap resultMap = new ResultMap.Builder(ms.getConfiguration(), ms.getId(), HashMap.class, emptyResultMapping).build();
//        resultMaps.add(resultMap);
//        builder.resultMaps(resultMaps);
//        builder.resultSetType(ms.getResultSetType());
//        builder.cache(ms.getCache());
//        builder.flushCacheRequired(ms.isFlushCacheRequired());
//        builder.useCache(ms.isUseCache());
//
//        return builder.build();
//    }
//
//    /*
//     * 获取要修改的列及其值 map
//     */
//    private  Map<String, Object> getParameter(SqlParserInfo sqlParserInfo) {
//        Map<String, Object> paramMap = Maps.newHashMap();
//        for(int i=0;i<sqlParserInfo.getColumns().size();i++){
//            Column column=sqlParserInfo.getColumns().get(i);
//            paramMap.put(column.getColumnName().replace("`",""),
//                    sqlParserInfo.getExpressions().get(i).toString().replace("'",""));
//        }
//        return paramMap;
//    }
//
//    /*
//     * 构建日志对象list
//     */
//    private List<CmCustomerMaintenanceLog> getCmCustomerMaintenanceLog(HistoryLog txnHistoryLog,
//                                                                       ArrayList<HashMap<String,
//            Object>> queryResults
//            ,Map<String, Object> updateDataMap,String type,String tableName) throws SegmentException {
//        List<CmCustomerMaintenanceLog> customerMaintenanceLogs = new ArrayList<>();
//        for(HashMap hashMap:queryResults){
//            Long id= hashMap.get("id") ==null?(Long)hashMap.get("ID"):(Long)hashMap.get("id");
//            Set<String> keySets=hashMap.keySet();
//            for(String result:keySets){
//                if("id".equalsIgnoreCase(result)){
//                    continue;
//                }
//                CmCustomerMaintenanceLog customerMaintenanceLog =new CmCustomerMaintenanceLog();
//                customerMaintenanceLog.setId(iSegmentService.getId("CmCustomerMaintenanceLog"));
//                customerMaintenanceLog.setChannel(txnHistoryLog.getChannel());
//                customerMaintenanceLog.setCustomerId(txnHistoryLog.getCustomerId());
//                customerMaintenanceLog.setTenantId(txnHistoryLog.getTenantId());
//                customerMaintenanceLog.setOrganizationId(txnHistoryLog.getOrganizationId());
//                customerMaintenanceLog.setUserId(txnHistoryLog.getUserId());
//                customerMaintenanceLog.setModifyTableName(tableName);
//                customerMaintenanceLog.setRecordId(id);
//                customerMaintenanceLog.setFieldName(result);
//                String oldValue = getParameterValue1(hashMap.get(result));
//                String newValue = getParameterValue1(updateDataMap.get(result));
//                if(StringUtils.endsWith(oldValue,newValue)){
//                    continue;
//                }
//                customerMaintenanceLog.setFieldValueOld(oldValue);
//                customerMaintenanceLog.setFieldValueNew("record_version_number".equalsIgnoreCase(result)?
//                        String.valueOf((Integer)hashMap.get(result)+1): newValue);
//                customerMaintenanceLog.setLogType(StringUtils.isBlank(type)?txnHistoryLog.getType():type);
//                customerMaintenanceLog.setRecordVersionNumber(1);
//                customerMaintenanceLog.setUpdateBy(txnHistoryLog.getUserId());
//                customerMaintenanceLogs.add(customerMaintenanceLog);
//            }
//        }
//        return customerMaintenanceLogs;
//    }
//    /*
//     * 获取注解
//     */
//    private EnableHistoryLogAnnotation getEnableHistoryLogAnnotationAnnotation(String namespace) throws ClassNotFoundException {
//        EnableHistoryLogAnnotation enableHistoryLog=null;
//        String className = namespace.substring(0,namespace.lastIndexOf('.'));
//        String methedName= namespace.substring(namespace.lastIndexOf('.') + 1);
//        Method[] ms = Class.forName(className).getMethods();
//        //遍历方法
//        for(Method m : ms){
//            if(m.getName().equals(methedName)){
//                enableHistoryLog = m.getAnnotation(EnableHistoryLogAnnotation.class);
//            }
//        }
//        return enableHistoryLog;
//    }
//    /*
//     * 获取执行后的语句
//     */
//    private String showSql(Configuration configuration, BoundSql boundSql) {
//        Object parameterObject = boundSql.getParameterObject();
//        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
//        if (!parameterMappings.isEmpty() && parameterObject != null) {
//            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
//            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
//                sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));
//
//            } else {
//                MetaObject metaObject = configuration.newMetaObject(parameterObject);
//                for (ParameterMapping parameterMapping : parameterMappings) {
//                    String propertyName = parameterMapping.getProperty();
//                    if (metaObject.hasGetter(propertyName)) {
//                        Object obj = metaObject.getValue(propertyName);
//                        sql = sql.replaceFirst("\\?", getParameterValue(obj));
//                    } else if (boundSql.hasAdditionalParameter(propertyName)) {
//                        Object obj = boundSql.getAdditionalParameter(propertyName);
//                        sql = sql.replaceFirst("\\?", getParameterValue(obj));
//                    }  else{
//                        Map map = (Map)metaObject ;
//                        sql = sql.replaceFirst("\\?", getParameterValue(map.get(propertyName)));
//                    }
//                }
//            }
//        }
//        return sql;
//    }
//    /*
//     * 获取参数值并转换为string
//     */
//    private static String getParameterValue(Object obj) {
//        String value;
//        if (obj instanceof String) {
//            value = "'" + obj.toString() + "'";
//        } else if (obj instanceof Date) {
//            DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
//            value = "'" + formatter.format(new Date()) + "'";
//        } else {
//            if (obj != null) {
//                value = obj.toString();
//            } else {
//                value = "";
//            }
//
//        }
//        return value;
//    }
//
//    /*
//     * 获取参数值并转换为string
//     */
//    private static String getParameterValue1(Object obj) {
//        String value;
//        if (obj instanceof String) {
//            value =  obj.toString();
//        } else if (obj instanceof Date) {
//            DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
//            value = formatter.format(new Date());
//        } else {
//            if (obj != null) {
//                value = obj.toString();
//            } else {
//                value = "";
//            }
//
//        }
//        return value;
//    }
//    /*
//     * 重构插入参数
//     */
//    private Object wrapCollection(final Object object) {
//        if (object instanceof Collection) {
//            DefaultSqlSession.StrictMap<Object> map = new DefaultSqlSession.StrictMap<>();
//            map.put("collection", object);
//            if (object instanceof List) {
//                map.put("list", object);
//            }
//            return map;
//        } else if (object != null && object.getClass().isArray()) {
//            DefaultSqlSession.StrictMap<Object> map = new DefaultSqlSession.StrictMap<>();
//            map.put("array", object);
//            return map;
//        }
//        return object;
//    }
//}
